﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TalksLog.Domain.Core;
using System.ComponentModel.DataAnnotations;
using TalksLog.Domain.ValueObjects;
using System.IO;
using System.Text.RegularExpressions;
using TalksLog.Domain.Account.Common;

namespace TalksLog.Domain.Account.Entities
{
    public enum Gender
    {
        Male,
        Female,
        Unknown
    }

    public enum AccountState
    {
        Unavailable,
        Available,
    }

    public class Account : EntityBase, IAggregateRoot
    {
        private Account() { }

        #region  Properies

        public string Name { get; set; }

        public string Password { get; set; }

        public Gender Gender { get; set; }

        public string Email { get; set; }

        public DateTime? Birthday { get; set; }

        public Address Address { get; set; }

        public Contacts Contacts { get; set; }

        public string ProfilePicture { get; set; }

        public string ThumbnailProfilePicture { get; set; }

        public DateTime Apply4RegisterTime { get; set; }

        public DateTime? RegisterTime { get; set; }

        public DateTime? LatestLoginTime { get; set; }

        public AccountState State { get; set; }

        public int Salt { get; set; }

        public virtual List<Account> SomeoneWhoFollowMe { get; set; }

        public virtual List<Account> SomeoneWhoIFollow { get; set; }

        #endregion

        # region About follow

        public void Follow(Account user)
        {
            if (IsFollowing(user))
            {
                throw new InvalidOperationException("已关注该用户");
            }

            if (SomeoneWhoIFollow == null)
            {
                SomeoneWhoIFollow = new List<Account>();
            }

            SomeoneWhoIFollow.Add(user);
        }

        public void UnFollow(Account user)
        {
            if (!IsFollowing(user))
            {
                throw new InvalidOperationException("没有关注该用户");
            }

            SomeoneWhoIFollow.Remove(user);
        }

        public bool IsFollowing(Account user)
        {
            if (SomeoneWhoIFollow == null)
            {
                return false;
            }
            return SomeoneWhoIFollow.Exists(u => u.Id == user.Id);
        }

        #endregion

        #region About account state

        public void Go2BlackRoom()
        {
            if (State == AccountState.Unavailable)
            {
                throw new InvalidOperationException("帐号已在小黑屋");
            }
            State = AccountState.Unavailable;
        }

        public void GoOutOfBlackRoom()
        {
            if (State == AccountState.Available)
            {
                throw new InvalidOperationException("帐号本不在小黑屋");
            }
            State = AccountState.Unavailable;
        }

        #endregion

        #region Abount mondify basic account's information

        public void MondifyPassword(string oldPassword, string newPasswrod)
        {
            string oldPasswordWithSalt = PasswordConverter.GetPasswordWithSalt(Email, oldPassword, Salt);

            if (oldPasswordWithSalt != Password)
            {
                throw new InvalidOperationException("原密码输入错误");
            }
            if (string.IsNullOrWhiteSpace(newPasswrod))
            {
                throw new ArgumentException("密码不能为空");
            }

            string newPasswordWithSalt = PasswordConverter.GetPasswordWithSalt(Email, newPasswrod, Salt);
            Password = newPasswordWithSalt;
        }

        public void SetProfilePicture(Stream profilePicture,Stream thumbnailProfilePicture)
        {
            
        }

        public void SetBasicInfo(Gender gender,DateTime? birthday,Address address, Contacts contacts)
        {
            Gender = gender;
            Birthday = birthday;
            Address = address;
            Contacts = contacts;
        }

        public void SetLatestLoginTime(DateTime time)
        {
            LatestLoginTime = time;
        }

        #endregion

        internal static Account Create(string name,
            string password,
            Gender gender,
            string email,
            DateTime? birthday,
            Address address,
            Contacts contacts)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("请输入名称");
            }
            if (string.IsNullOrWhiteSpace(password))
            {
                throw new ArgumentException("请输入密码");
            }
            if (string.IsNullOrWhiteSpace(email))
            {
                throw new ArgumentException("请输入邮箱");
            }
            if (!Regex.IsMatch(email, @"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"))
            {
                throw new ArgumentException("邮箱格式不正确");
            }

            Account account = new Account();
            account.Name = name;
            account.Salt = GetRandomInt();
            account.Password = PasswordConverter.GetPasswordWithSalt(email, password, account.Salt);
            account.Email = email;
            account.State = AccountState.Available;
            account.SetBasicInfo(gender, birthday, address, contacts);

            return account;
        }

        private static int GetRandomInt()
        {
            Random random = new Random();
            return random.Next(111112, 99999);
        }
    } 
}
